{
 "cells": [
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn.functional as F\n",
    "from torch import nn"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T13:44:33.215141Z",
     "start_time": "2024-03-30T13:44:32.031865Z"
    }
   },
   "id": "efbb131c3860b47f",
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 5.4.1. 不带参数的层"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "9405afc593e9b7be"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class CenteredLayer(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "\n",
    "    def forward(self, X):\n",
    "        return X - X.mean()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T14:45:43.945219Z",
     "start_time": "2024-03-30T14:45:43.935890Z"
    }
   },
   "id": "78a82284cc461f2d",
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([-2., -1.,  0.,  1.,  2.])"
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "layer = CenteredLayer()\n",
    "layer(torch.FloatTensor([1, 2, 3, 4, 5]))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T13:44:51.729075Z",
     "start_time": "2024-03-30T13:44:51.666497Z"
    }
   },
   "id": "f68806a2a9db84a7",
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T13:45:25.315053Z",
     "start_time": "2024-03-30T13:45:25.311604Z"
    }
   },
   "id": "780037836737ab96",
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "tensor(-1.8626e-09, grad_fn=<MeanBackward0>)"
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y = net(torch.rand(4, 8))\n",
    "Y.mean()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T13:45:46.618810Z",
     "start_time": "2024-03-30T13:45:46.601125Z"
    }
   },
   "id": "8238edfae42e0c58",
   "execution_count": 6
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 5.4.2. 带参数的层"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "3df98df47ff61a17"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class MyLinear(nn.Module):\n",
    "    def __init__(self, in_units, units):\n",
    "        super().__init__()\n",
    "        self.weight = nn.Parameter(torch.randn(in_units, units))\n",
    "        self.bias = nn.Parameter(torch.randn(units))\n",
    "\n",
    "    def forward(self, X):\n",
    "        return F.relu(torch.matmul(X, self.weight) + self.bias)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T14:44:14.516936Z",
     "start_time": "2024-03-30T14:44:14.502562Z"
    }
   },
   "id": "520dbd9b5e396746",
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "Parameter containing:\ntensor([[-0.8428, -2.0890,  0.7672],\n        [ 1.3508,  0.1319,  0.3962],\n        [-0.8244,  0.4160,  0.3040],\n        [ 2.1888, -0.6475,  0.1268],\n        [-2.4519,  0.2456,  1.4325]], requires_grad=True)"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear = MyLinear(5, 3)\n",
    "linear.weight"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T14:44:38.491208Z",
     "start_time": "2024-03-30T14:44:38.471968Z"
    }
   },
   "id": "60733bf20912a375",
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([[0.8815, 2.3383, 0.0000],\n        [3.1104, 2.4921, 0.0000]], grad_fn=<ReluBackward0>)"
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear(torch.randn(2, 5))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T14:45:17.260910Z",
     "start_time": "2024-03-30T14:45:17.244703Z"
    }
   },
   "id": "c853448d1e1a609b",
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([[0.],\n        [0.]], grad_fn=<ReluBackward0>)"
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))\n",
    "net(torch.rand(2, 64))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-30T14:52:13.396190Z",
     "start_time": "2024-03-30T14:52:13.390201Z"
    }
   },
   "id": "ad51b4547733fa9a",
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "ccdb831387a8819f"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
